//! JIT预编译器
//!
//! 在构建阶段完成JIT编译，实现零延迟启动

use crate::jit::{PipitJIT, JITOptimizationLevel};
use crate::vm::{VirtualMachine, Instruction};
use crate::Value;
use std::fs;
use std::path::Path;

/// JIT预编译器
pub struct Precompiler {
    jit: PipitJIT,
}

impl Precompiler {
    /// 创建新的预编译器
    pub fn new(optimization_level: JITOptimizationLevel) -> Self {
        Self {
            jit: PipitJIT::new(optimization_level),
        }
    }

    /// 预编译字节码文件
    pub fn precompile_bytecode_file(&mut self, input_path: &str, output_path: &str) -> Result<(), String> {
        let content = fs::read_to_string(input_path)
            .map_err(|e| format!("无法读取文件: {}", e))?;
        
        let bytecode = self.parse_bytecode(&content)?;
        let serialized = self.serialize_bytecode(&bytecode);
        
        self.jit.precompile_module("main", &serialized)
            .map_err(|e| format!("预编译失败: {:?}", e))?;
        
        // 保存预编译结果
        let precompiled_data = self.create_precompiled_data(&serialized)?;
        fs::write(output_path, precompiled_data)
            .map_err(|e| format!("无法写入文件: {}", e))?;
        
        Ok(())
    }

    /// 预编译字节码字符串
    pub fn precompile_bytecode(&mut self, bytecode: &[Instruction], module_name: &str) -> Result<Vec<u8>, String> {
        let serialized = self.serialize_bytecode(bytecode);
        
        self.jit.precompile_module(module_name, &serialized)
            .map_err(|e| format!("预编译失败: {:?}", e))?;
        
        Ok(serialized)
    }

    /// 解析字节码字符串
    fn parse_bytecode(&self, content: &str) -> Result<Vec<Instruction>, String> {
        let mut instructions = Vec::new();
        
        for line in content.lines() {
            let line = line.trim();
            if line.is_empty() || line.starts_with("//") {
                continue;
            }
            
            let parts: Vec<&str> = line.split_whitespace().collect();
            if parts.is_empty() {
                continue;
            }
            
            let instr = match parts[0] {
                "Push" => {
                    let value = parts[1].parse::<i32>().unwrap_or(0);
                    Instruction::Push(Value::Integer(value))
                },
                "Add" => Instruction::Add,
                "Sub" => Instruction::Sub,
                "Mul" => Instruction::Mul,
                "Div" => Instruction::Div,
                "Print" => Instruction::Print,
                "Halt" => Instruction::Halt,
                "StoreVar" => {
                    let idx = parts[1].parse::<i32>().unwrap_or(0);
                    Instruction::StoreVar(idx)
                },
                "LoadVar" => {
                    let idx = parts[1].parse::<i32>().unwrap_or(0);
                    Instruction::LoadVar(idx)
                },
                "Jump" => {
                    let offset = parts[1].parse::<usize>().unwrap_or(0);
                    Instruction::Jump(offset)
                },
                "JumpIfFalse" => {
                    let offset = parts[1].parse::<usize>().unwrap_or(0);
                    Instruction::JumpIfFalse(offset)
                },
                _ => continue,
            };
            
            instructions.push(instr);
        }
        
        Ok(instructions)
    }

    /// 序列化字节码
    fn serialize_bytecode(&self, bytecode: &[Instruction]) -> Vec<u8> {
        let mut serialized = Vec::new();
        for instr in bytecode {
            match instr {
                Instruction::Push(Value::Integer(val)) => {
                    serialized.push(0x01);
                    serialized.extend_from_slice(&val.to_le_bytes());
                }
                Instruction::Add => serialized.push(0x02),
                Instruction::Sub => serialized.push(0x03),
                Instruction::Mul => serialized.push(0x04),
                Instruction::Div => serialized.push(0x05),
                Instruction::Print => serialized.push(0x06),
                Instruction::Halt => serialized.push(0x07),
                Instruction::StoreVar(idx) => {
                    serialized.push(0x08);
                    serialized.extend_from_slice(&idx.to_le_bytes());
                }
                Instruction::LoadVar(idx) => {
                    serialized.push(0x09);
                    serialized.extend_from_slice(&idx.to_le_bytes());
                }
                Instruction::JumpIfFalse(offset) => {
                    serialized.push(0x0A);
                    serialized.extend_from_slice(&(*offset as i32).to_le_bytes());
                }
                Instruction::Jump(offset) => {
                    serialized.push(0x0B);
                    serialized.extend_from_slice(&(*offset as i32).to_le_bytes());
                }
                _ => {}
            }
        }
        serialized
    }

    /// 创建预编译数据格式
    fn create_precompiled_data(&self, bytecode: &[u8]) -> Result<Vec<u8>, String> {
        let mut data = Vec::new();
        
        // 添加预编译标识
        data.extend_from_slice(b"PREC");
        
        // 添加字节码长度
        data.extend_from_slice(&(bytecode.len() as u32).to_le_bytes());
        
        // 添加字节码
        data.extend_from_slice(bytecode);
        
        Ok(data)
    }

    /// 获取预编译统计信息
    pub fn get_stats(&self) -> &crate::jit::JITStats {
        &self.jit.get_stats()
    }
}

/// 预编译工具函数
pub fn precompile_at_build_time(
    input_path: &str,
    output_path: &str,
    optimization_level: JITOptimizationLevel,
) -> Result<(), String> {
    let mut precompiler = Precompiler::new(optimization_level);
    precompiler.precompile_bytecode_file(input_path, output_path)
}

/// 在构建脚本中使用的预编译宏
#[macro_export]
macro_rules! precompile_module {
    ($input:expr, $output:expr, $level:expr) => {{
        use $crate::jit::precompiler::precompile_at_build_time;
        precompile_at_build_time($input, $output, $level)
    }};
}